home *** CD-ROM | disk | FTP | other *** search
- PROGRAM encode;
-
- {$F+}
-
- { ------------------------------------------------------------------
-
- This program and its associates implement in Turbo Pascal v5
- the aritmetic encoding/decoding algorithms presented in the papers
-
- "Arithmetic Coding for Data Compression"
-
- by Ian H. Witten
- Radford M. Neal
- John G. Cleary
-
- pp 520 - 540 of June 1987 Communications of the ACM
-
- and
-
- "An Adaptive Dependency Source Model For Data Compression"
-
- by David M. Abrahamson
-
- pp 77 - 83 of January 1989 Communications of the ACM
-
- ------------------------------------------------------------------
-
- Implemented by Ken Westerback : CompuServe 73547,3520
-
- version 1.0 released 89/02/19
- version 2.0 released 89/02/27
-
- These programs, units and associated documentation are released
- into the public domain to be used and abused as your whims
- dictate.
-
- Feel free to distribute/incorporate/improve as desired.
-
- >>>>> Use at your own risk! <<<<<
-
- Comments and suggestions welcome via CompuServe.
-
- ------------------------------------------------------------------
- }
-
-
- USES overlay
- ,dos
- ,arith_en { arithmetic encoding implementation }
- ,fix_mod { fixed coding model }
- ,adap_mod { adaptive coding model }
- ,adp_mod { adaptive dependency source coding model }
- ;
-
- {$O fix_mod }
- {$O adap_mod }
- {$O adp_mod }
-
- var symbol : integer; { symbol for character being encoded }
- encodee : file; { file to encode }
- chars_in : longint; { characters read from encodee }
- chars_out : longint; { (bits_sent + 7) div 8 }
- chars_left : longint; { characters left to read from encodee }
-
- char_buf : array[ 0..2047] of char; { chunks we read encodee in }
- chars_in_buf : word;
- i : word;
-
- model_name : string;
-
- select_symbol : function ( ch : char ) : integer;
- update_model : procedure ( symbol : integer ) ;
-
-
- procedure open_files;
-
- var s : pathstr;
- param1, param2, param3 : string;
-
- begin
-
- { must have three parameters - in/out files and model to use }
-
- if ( paramcount < 3 ) then
- begin
- writeln ;
- writeln ( 'usage : encode <model> <input file> <output file>' );
- writeln;
- halt;
- end;
-
- param1 := paramstr ( 1 );
- param2 := paramstr ( 2 );
- param3 := paramstr ( 3 );
-
- writeln ;
- write ( '"', param2, '" will be encoded as "', param3, '"' );
-
- start_encoding ( param3, param1[ 1 ] );
-
- { second parameter is file to encode }
-
- s := fsearch ( param2, '' );
-
- if s <> '' then
- assign ( encodee, s )
- else
- begin
- writeln ;
- writeln ( 'encode : can''t find file "', paramstr(1), '"' );
- writeln;
- halt;
- end;
-
- Reset ( encodee, 1 );
-
- chars_left := filesize ( encodee );
- chars_in := 0;
-
- { third parameter is desired name of encoded file. }
- { }
- { note : will write over any file of same name! }
-
- ovrinit ( 'encode.ovr' );
-
- if ovrresult <> ovrok then
- begin
- writeln;
- writeln ( 'encode : overinit failed (', ovrresult, ')' );
- writeln;
- halt;
- end;
-
- case param1[ 1 ] of
-
- 'f' : begin
- model_name := fix_mod.model_name;
- fix_mod.start_model;
- select_symbol := fix_mod.select_symbol;
- update_model := fix_mod.update_model;
- end;
-
- 'a' : begin
- model_name := adap_mod.model_name;
- adap_mod.start_model;
- select_symbol := adap_mod.select_symbol;
- update_model := adap_mod.update_model;
- end;
-
- 'd' : begin
- model_name := adp_mod.model_name;
- adp_mod.start_model;
- select_symbol := adp_mod.select_symbol;
- update_model := adp_mod.update_model;
- end;
-
- else begin
- writeln;
- writeln ( 'encode : invalid model "', param1[ 1 ], '"' );
- writeln;
- halt;
- end;
-
- end; { model case }
-
- writeln ( ' using ', model_name );
-
- end; { open files }
-
- procedure close_files;
- begin
-
- chars_out := done_encoding;
-
- close ( encodee );
-
- end; { close_files }
-
- BEGIN
-
- writeln ;
- writeln ( 'TPascal Arithmetic Coding, by Ken Westerback, version 2.0 89/02/27' );
-
- open_files;
-
- while not eof ( encodee ) do
- begin
-
- chars_in_buf := 2048;
- if chars_left < 2048 then chars_in_buf := chars_left;
-
- dec ( chars_left, chars_in_buf );
-
- blockread ( encodee, char_buf, chars_in_buf, chars_in_buf );
-
- inc ( chars_in, chars_in_buf );
-
- for i := 0 to chars_in_buf-1 do
- begin
- symbol := select_symbol ( char_buf[ i ] );
- encode_symbol ( symbol );
- update_model ( symbol );
- end;
-
- end;
-
- close_files;
-
- writeln ;
- writeln ( ' characters read : ', chars_in );
- writeln ( ' characters written : ', chars_out );
- writeln ;
- writeln ( ' ', (100 - (chars_out/chars_in)*100):4:2, ' % compression' );
- writeln ;
-
- end. { arithmetic encoding of a file }